/*
 * GrantRequestsListView.java
 *
 * Created on October 29, 2008, 11:22 AM
 */

package researchgrants.parts.GrantRequest;

import researchgrants.parts.GrantRequest.filters.GrantRequestsListFilters;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import researchgrants.parts.GrantRequest.grantOfficer.GrantOfficer;
import researchgrants.parts.GrantRequest.statusChanges.GrantRequestStatusChange;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import researchgrants.utils.Constants;
import researchgrants.parts.pi.Pi;
import researchgrants.parts.pi.PisList;
import researchgrants.utils.MultiSelectList;
import researchgrants.utils.MyDialog;

/**
 * A view class for displaying a list of grant requests (GrantRequestList).
 * Support filtering of the current list
 * For each of the list's GrantRequests, shows a summary, and allow the user to view any GrantRequest individually in a seperate GrantRequestView
 * @author  ohad
 */
public class GrantRequestsListView extends MyDialog {

    private JPanel pnlGrantRequestsList;
    
    // the lists
    // the original list
    private GrantRequestsList originalList;
    // the currently-filtered list
    private GrantRequestsList list;

    // Filters:
    private MultiSelectList grantOfficersMultiSelectListFilter;
    private JTextField freeTextFilter;
//    DateRangeSelector deadlineFilter;
            
    /** Creates new form GrantRequestsListView */
    GrantRequestsListView(Window parent, GrantRequestsList list, String title) {
        super(parent);
        setTitle(title);

        initComponents();
        this.originalList=list;
        reloadOriginalList();
        
        
        
        ////////////////////////////////////////////
        // the content of the filters 
        ////////////////////////////////////////////
        
        JPanel pnlFilters=new JPanel(new BorderLayout(0, 0));
        splitContent.setTopComponent(pnlFilters);
        JLabel lblFiltersCaption=new JLabel("Filters");
        lblFiltersCaption.setHorizontalAlignment(0);
        MyDialog.changeToTitleLabel(lblFiltersCaption);
        pnlFilters.add(lblFiltersCaption, BorderLayout.NORTH);
        JPanel pnlFilters2=new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0));
        pnlFilters.add(pnlFilters2, BorderLayout.CENTER);
        pnlFilters2.setMinimumSize(new Dimension(0, 0));
        JPanel pnlFilters3=new JPanel(new GridBagLayout());
        pnlFilters2.add(pnlFilters3);

        
        GridBagConstraints gridBagConstraints=new GridBagConstraints();
        gridBagConstraints.gridx=0;
        gridBagConstraints.gridy=0;
        
        // Adds the free-text filter
        {
            JLabel lblCaption = new JLabel("Free text search: ");
            pnlFilters3.add(lblCaption, gridBagConstraints);
            gridBagConstraints.gridx++;
            freeTextFilter=new JTextField("");
            freeTextFilter.setColumns(10);
            freeTextFilter.addKeyListener(new KeyListener() {

                public void keyTyped(KeyEvent e) {
                    redoFilters();
                }

                public void keyPressed(KeyEvent e) {
                    redoFilters();
                }

                public void keyReleased(KeyEvent e) {
                    redoFilters();
                }
            });
            pnlFilters3.add(freeTextFilter, gridBagConstraints);
            gridBagConstraints.gridx=0;
            gridBagConstraints.gridy++;
        }        
        

        // Adds the Grant Officer filter
        {
            JLabel lblCaption = new JLabel("Grant Officer: ");
            pnlFilters3.add(lblCaption, gridBagConstraints);
            gridBagConstraints.gridx++;
            List<GrantOfficer> allGrantOfficers = GrantOfficer.getAllGrantOfficers();
            SortedMap<String, String> map=new TreeMap<String, String>();
            for (Iterator<GrantOfficer> it = allGrantOfficers.iterator(); it.hasNext();) {
                GrantOfficer grantOfficer = it.next();
                map.put(grantOfficer.toListId(), grantOfficer.toListValue());
            }
            grantOfficersMultiSelectListFilter=new MultiSelectList(map);
            grantOfficersMultiSelectListFilter.addChangeListener(new ChangeListener() {

                public void stateChanged(ChangeEvent e) {
                    redoFilters();
                }
            });
            pnlFilters3.add(grantOfficersMultiSelectListFilter.getComponent(), gridBagConstraints);
            gridBagConstraints.gridx=0;
            gridBagConstraints.gridy++;
        }        
        
        
//        // Adds the deadline filter
//        {
//            JLabel lblCaption = new JLabel("Deadline: ");
//            pnlFilters3.add(lblCaption, gridBagConstraints);
//            gridBagConstraints.gridx++;
//            deadlineFilter=new DateRangeSelector();
//            deadlineFilter.addChangeListener(new ChangeListener() {
//
//                public void stateChanged(ChangeEvent e) {
//                    redoFilters();
//                }
//            });
//            pnlFilters3.add(deadlineFilter, gridBagConstraints);
//            gridBagConstraints.gridx=0;
//            gridBagConstraints.gridy++;
//        }        
                

        
        
        /////////////////////////////////////
        // The content of the list
        /////////////////////////////////////
        
        JPanel pnlListContent=new JPanel(new BorderLayout(0, 0));
        splitContent.setBottomComponent(pnlListContent);

        JLabel lblListCaption=new JLabel("Records");
        lblListCaption.setHorizontalAlignment(0);
        MyDialog.changeToTitleLabel(lblListCaption);
        pnlListContent.add(lblListCaption, BorderLayout.NORTH);
        
        JPanel pnlListContent2=new JPanel(new BorderLayout(0, 0));
        pnlGrantRequestsList=new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0));
        pnlListContent2.add(pnlGrantRequestsList, BorderLayout.NORTH);
        pnlListContent.add(pnlListContent2, BorderLayout.CENTER);
        pnlGrantRequestsList.setMinimumSize(new Dimension(0,0));

//        splitContent.setDividerLocation((int)lblFiltersCaption.getMinimumSize().getHeight());

        // display the list, with all empty filters
        redoFilters();
        
        pack();

    }
    
    // used to refilter
    private void reloadOriginalList() {
        try {
            list = (GrantRequestsList) originalList.clone();
        } catch (CloneNotSupportedException ex) {
            Logger.getLogger(GrantRequestsListView.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    
    // displays the list according to the current filters
    // filters the list from the original and displays it
    private void redoFilters() {
        // loads the original list
        reloadOriginalList();
        
        // filter the list by the free text
        if (!freeTextFilter.getText().equals("")) {
            GrantRequestsListFilters.filterByFreeText(list, freeTextFilter.getText());
        }

        // filter the list by the selected grant officers
        Collection<GrantOfficer> selectedGrantOfficers=new LinkedList<GrantOfficer>();
        Collection<Object> selectedGrantOfficersKeys = grantOfficersMultiSelectListFilter.getSelectedKeys();
        if (selectedGrantOfficersKeys.size()>0) {
            for (Iterator it = selectedGrantOfficersKeys.iterator(); it.hasNext();) {
                GrantOfficer grantOfficer=GrantOfficer.fromListId((String)it.next());
                selectedGrantOfficers.add(grantOfficer);
                
            }
            GrantRequestsListFilters.filterByGrantOfficers(list, selectedGrantOfficers);
        }
        
//      // filter the list with the range of deadline dates
//        if ((deadlineFilter.getFromDate()!=null) || (deadlineFilter.getToDate()!=null)) {
//            GrantRequestsListFilters.filterByDeadline(list, deadlineFilter.getFromDate(), deadlineFilter.getToDate());
//        }
        
        // displays the current, filtered list
        reDisplayListContent();
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        splitContent = new javax.swing.JSplitPane();

        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
        setName("Form"); // NOI18N
        addComponentListener(new java.awt.event.ComponentAdapter() {
            public void componentResized(java.awt.event.ComponentEvent evt) {
                formComponentResized(evt);
            }
        });

        splitContent.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT);
        splitContent.setAutoscrolls(true);
        splitContent.setName("splitContent"); // NOI18N
        splitContent.setOneTouchExpandable(true);
        splitContent.setOpaque(false);
        getContentPane().add(splitContent, java.awt.BorderLayout.CENTER);

        pack();
    }// </editor-fold>//GEN-END:initComponents

private void formComponentResized(java.awt.event.ComponentEvent evt) {//GEN-FIRST:event_formComponentResized
}//GEN-LAST:event_formComponentResized

    // displays a single grant request 
    private static class ViewGrantRequestListener implements ActionListener {

        private final GrantRequest grantRequest;
        private final GrantRequestsListView parent;
        public ViewGrantRequestListener(GrantRequest grantRequest, GrantRequestsListView parent) {
            this.grantRequest = grantRequest;
            this.parent = parent;
        }

        public void actionPerformed(ActionEvent e) {
            // shows the grant request in a seperate window
            grantRequest.show(parent);
            // refreshed the list after the grant request has been shown, in case a change within was issued.
            parent.reDisplayListContent();
        }
    }

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JSplitPane splitContent;
    // End of variables declaration//GEN-END:variables

    // displays the list of records from the current list
    private void reDisplayListContent() {

        pnlGrantRequestsList.removeAll();
        
        JLabel lblTemp;
        
        GridBagLayout gridBagLayout=new GridBagLayout();
        pnlGrantRequestsList.setLayout(gridBagLayout);
        GridBagConstraints gridBagConstraints = new GridBagConstraints();
        gridBagConstraints.ipadx=8;
        gridBagConstraints.ipady=8;
        gridBagConstraints.gridheight=1;
        gridBagConstraints.gridwidth=1;
        
        ///////////////////////
        // Adds the headers
        ///////////////////////
        
        gridBagConstraints.gridx=0;
        gridBagConstraints.gridy=0;
        lblTemp=new JLabel("ID", SwingConstants.CENTER);
        lblTemp.setFont(Constants.listHeaderFont);
        pnlGrantRequestsList.add(lblTemp, gridBagConstraints);
        gridBagConstraints.gridx++;

        lblTemp=new JLabel("Title", SwingConstants.CENTER);
        lblTemp.setFont(Constants.listHeaderFont);
        pnlGrantRequestsList.add(lblTemp, gridBagConstraints);
        gridBagConstraints.gridx++;

        lblTemp=new JLabel("Officer", SwingConstants.CENTER);
        lblTemp.setFont(Constants.listHeaderFont);
        pnlGrantRequestsList.add(lblTemp, gridBagConstraints);
        gridBagConstraints.gridx++;
        
        lblTemp=new JLabel("PIs", SwingConstants.CENTER);
        lblTemp.setFont(Constants.listHeaderFont);
        pnlGrantRequestsList.add(lblTemp, gridBagConstraints);
        gridBagConstraints.gridx++;

        lblTemp=new JLabel("Status", SwingConstants.CENTER);
        lblTemp.setFont(Constants.listHeaderFont);
        pnlGrantRequestsList.add(lblTemp, gridBagConstraints);
        gridBagConstraints.gridx++;

        lblTemp=new JLabel("Action", SwingConstants.CENTER);
        lblTemp.setFont(Constants.listHeaderFont);
        pnlGrantRequestsList.add(lblTemp, gridBagConstraints);
        gridBagConstraints.gridx++;
        
        int columnCount=gridBagConstraints.gridx;
        gridBagConstraints.gridx=0;
        gridBagConstraints.gridy++;

        // maximum records to show
        final int MAX_LINES=20;
        
        ////////////////////////////////////
        // Adds the individual records
        ////////////////////////////////////
        
        Iterator<GrantRequest> itGrantRequests = list.iterator();
        while(itGrantRequests.hasNext() && gridBagConstraints.gridy<=MAX_LINES) {
            GrantRequest grantRequest = itGrantRequests.next();

            lblTemp=new JLabel(Integer.toString(grantRequest.getId()), SwingConstants.LEFT);
            lblTemp.setFont(Constants.listRegularFont);
            pnlGrantRequestsList.add(lblTemp, gridBagConstraints);
            gridBagConstraints.gridx++;

            lblTemp=new JLabel(grantRequest.getCurrentTitle(), SwingConstants.LEFT);
            lblTemp.setFont(Constants.listRegularFont);
            pnlGrantRequestsList.add(lblTemp, gridBagConstraints);
            gridBagConstraints.gridx++;

            GrantOfficer grantOfficer=grantRequest.getCurrentGrantOfficer();
            lblTemp=new JLabel(grantOfficer.getName(), SwingConstants.LEFT);
            lblTemp.setFont(Constants.listRegularFont);
            pnlGrantRequestsList.add(lblTemp, gridBagConstraints);
            gridBagConstraints.gridx++;

            // summarizing the list of pis to show
            PisList pisList=grantRequest.getCurrentPis();
            StringBuffer pisDisplayString=new StringBuffer();
            
            for (Iterator<Pi> itPis = pisList.iterator(); itPis.hasNext();) {
                Pi pi = itPis.next();
                pisDisplayString.append(pi.getShortForm());
                if (itPis.hasNext()) {
                    pisDisplayString.append(", ");
                }
            }
            
            lblTemp=new JLabel(pisDisplayString.toString(), SwingConstants.LEFT);
            lblTemp.setFont(Constants.listRegularFont);
            pnlGrantRequestsList.add(lblTemp, gridBagConstraints);
            gridBagConstraints.gridx++;

            
            lblTemp=new JLabel(GrantRequestStatusChange.getStatusChangeTitle(grantRequest.getLastStatusChange()), SwingConstants.LEFT);
            lblTemp.setFont(Constants.listRegularFont);
            pnlGrantRequestsList.add(lblTemp, gridBagConstraints);
            gridBagConstraints.gridx++;

            JButton btn=new JButton("View");
            btn.addActionListener(new ViewGrantRequestListener(grantRequest, this));
            pnlGrantRequestsList.add(btn, gridBagConstraints);
            
            gridBagConstraints.gridx=0;
            gridBagConstraints.gridy++;
        }
        
        // if more records exist than displayed
        if (itGrantRequests.hasNext()) {
            gridBagConstraints.gridwidth=columnCount;
            pnlGrantRequestsList.add(new JLabel("--- More records exist than shown ---"), gridBagConstraints);
        }
        
        pack();
        setLocationRelativeTo(getParent());
        setVisible(true);

    }

}
